<?php
/**
 * 
 * @author Elwin
 * @date 2013-03-14
 */
interface IDbTreeCommpenont
{
	public function initialized($setting, $data);
	
	// public function getChildren($path);
	
	// public function move($id, $target);
	
	// public function reorder($parent, $moved, $target, $before);
	
	// public function getAlias();
	
	// public function getNodeTypes();
	
	// public function getLabels();
}
abstract class CDbTree
{
	// 节点路径
	private $path;
	// 节点id
	public $idKey;
	// 父节点id
	public $pidKey;
	// 节点名称
	public $nameKey;
	// 树形的数组
	private $_branch;
	// 树的子节点
	protected $children = 'children';
	// 树的节点深度
	protected $depth = 'depth';
	// 拖动到指定节点前
	protected $prev = 'prev';
	// 拖动到指定节点后
	protected $next = 'next';
	// 拖动到指定节点下(分两种,它的某个子节点前或后)
	protected $inner = 'inner';
	/**
	 * 调用的model
	 *
	 * @var CModel $_model
	 */
	private $_model = '';
	/**
	 *
	 * @var array $dragType
	 */
	protected $dragType = array (
			'prev','next','inner' 
	);
	
	/**
	 * 初始化数组的索引名称
	 * idKey 类的id pIdkey 父类id nameKey 类的名称 rootPid 根节点ID
	 * $setting = array (
	 * 'idKey' => 'id','pidKey' => 'pid','nameKey' => 'name','rootPid' =>
	 * '','modelName' => ''
	 * );
	 *
	 * $data = array (
	 * array (
	 * 'id' => 1,'pid' => 0,'name' => 'name1'
	 * ),array (
	 * 'id' => 2,'pid' => 0,'name' => 'name2'
	 * )
	 * );
	 *
	 * @param array $setting 设置树的节点数组索引
	 * @param array $data 数组
	 */
	public function initialized($setting, $data = array())
	{
		if (empty ( $data ) && class_exists ( $setting ['modelName'] ))
		{
			$this->_model = new $setting ['modelName'] ();
			// $data = $this->_model->findAll ();
		}
		if (! is_array ( $data ))
			throw new CHttpException ( 403, '$data参数必须是数组!' );
		$element = current ( $data );
		$keys = array_keys ( $element );
		foreach ( $setting as $keyName => $value )
		{
			$name = substr ( $keyName, 0, - 3 );
			$ext = substr ( $keyName, - 3 );
			if (! in_array ( $name, $keys ) && ($ext = substr ( $keyName, - 3 )) == "Key")
				throw new CHttpException ( 403, '检查$setting参数与$data参数是否正确!' );
			$this->$keyName = $value;
		}
		$this->_branch = self::buildTree ( $data, 0 );
	}
	/**
	 * 返回生成的二叉树
	 *
	 * @return array
	 */
	public function getBranch()
	{
		return $this->_branch;
	}
	
	// abstract public function initCssJs();
	/**
	 * 创建树形数组
	 * example:array();
	 *
	 * @param array $elements 二维数组
	 * @param int $parentId 父ID
	 * @return array $branch 返回树形数组
	 */
	public function buildTree(array $elements, $parentId = 0, $depth = 1)
	{
		$branch = array ();
		foreach ( $elements as $element )
		{
			if ($element [$this->pidKey] == $parentId)
			{
				$element [$this->depth] = $depth;
				$children = $this->buildTree ( $elements, $element [$this->idKey], ++ $depth );
				$depth --;
				if ($children)
				{
					$element [$this->children] = $children;
				}
				$branch [] = $element;
			}
		}
		return $branch;
	}
	public function insertBefore()
	{
	}
	public function insertAfter()
	{
	}
	public function isRoot()
	{
	}
	/**
	 *
	 * @param array $tree
	 * @param int $depth
	 *
	 */
	public function getDepth($tree, $depth = 1)
	{
	}
	/**
	 *
	 * @param array $tree
	 * @return string
	 */
	public function printTree(array $tree)
	{
		$list = '<ul>';
		foreach ( $tree as $chilren )
		{
			$list .= '<li>';
			$list .= $chilren [$this->nameKey];
			if (! empty ( $chilren [$this->children] ))
			{
				$list .= self::printTree ( $chilren [$this->children] );
			}
			$list .= '</li>';
		}
		$list .= '</ul>';
		return $list;
	}
	
	/**
	 * 树的索引路径(key1_key2_....)
	 *
	 * @param array $array 树形的数组
	 * @param array $path 树节点的索引数组
	 * @return array $result 返回数组结果
	 */
	public function path(array $array, array $path = array())
	{
		$result = array ();
		foreach ( $array as $key => $val )
		{
			$currentPath = array_merge ( $path, array (
					$key 
			) );
			if (is_array ( $val ))
			{
				$result = array_merge ( $result, self::path ( $val, $currentPath ) );
			} else
			{
				$currentPath [] = $val;
				$result [] = join ( '_', $currentPath );
			}
		}
		return $result;
	}
	public function getValue()
	{
	}
	public function getNode()
	{
	}
	public function addNode()
	{
	}
	public function remove()
	{
	}
	public function &addItem(TreeItem $item)
	{
	}
}
/**
 * *********************************************************
 */
// Category Item class
class category_item
{
	var $cat_id;
	var $depth;
	var $cat_title;
	var $cat_parent_id;
	var $cat_long_title;
	function category_item($cat_id, $depth, $cat_title, $cat_parent_id, $cat_long_title = '')
	{
		$this->cat_id = $cat_id;
		$this->depth = $depth;
		$this->cat_title = $cat_title;
		$this->cat_parent_id = $cat_parent_id;
		$this->cat_long_title = $cat_long_title;
	}
}

/**
 * **********************************************************
 */
// Builds the category list for the category select

$list = array ();
function build_list($cat_array, $item = '', $depth = 0)
{
	global $template;
	global $list;
	
	foreach ( $cat_array as $category )
	{
		$loop_item = "$item$category[cat_title]";
		
		$category_item = new category_item ( $category [cat_id], $depth, $category [cat_title], $category [cat_parent_id], $loop_item );
		$list [] = $category_item;
		
		if (count ( $category [children] ) > 0)
		{
			$depth ++;
			build_list ( $category [children], $loop_item . " > ", $depth );
			$depth --;
		}
		
		$loop_item = '';
	}
	
	return $list;
}

/**
 * **********************************************************
 */
function tree_add($tree, $parent_id, $object, $cat_id)
{
	if ($parent_id == '0' and $object ['cat_id'] == $cat_id)
	{
		$tree [$object [cat_id]] = $object;
		return $tree;
	}
	
	if ($tree)
	{
		foreach ( $tree as $key => $value )
		{
			$current = $tree [$key];
			if ($current [$cat_id] == $parent_id)
			{
				$tree [$key] ['children'] [$object ['cat_id']] = $object;
			} else
			{
				$tree [$key] [children] = tree_add ( $current [children], $parent_id, $object, $cat_id );
			}
		}
	}
	
	return $tree;
}

/*
 * $query = " select from categories order by cat_id "; $result = $db->sql_query
 * ( $query ); while ( $category = $db->sql_fetchrow ( $result ) ) { $children =
 * array (); $category [children] = $children; $cat_id = $category [cat_id];
 * $cat_parent_id = $category [cat_parent_id]; $cat_tree = tree_add ( $cat_tree,
 * $cat_parent_id, $category, $cat_id ); } $cat_list = build_list ( $cat_tree );
 */
?>